/**
 * This file is a part of qloudgen-rul. 
 * You can redistribute qloudgen-rul and/or modify it under the terms of the Lesser GNU General Public License version 3. 
 * qloudgen-rul is distributed WITHOUT ANY WARRANTY. 
 *
 * See the Lesser GNU General Public License for more details at http://www.gnu.org/licenses/. 
 **/
package org.qloudgen.rul.drools.rule;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.qloudgen.sec.util.ExceptionUtil;

/**
 * <p>Title: Drools Implementation</p>
 * <p>Description: Wrappered jboss drools rules engine implementation.</p>
 * <p>Copyright: qloudgen/rul 2014</p>
 * @author <a href="mailto:hyq.dd.sun@gmail.com">glue.3M</a>
 */
public abstract class AbstractDroolsRuleRunner implements DroolsRuleRunner {
	/**
	 * Log output.
	 */
	private final static Logger logger = LoggerFactory.getLogger( AbstractDroolsRuleRunner.class );
	
	/**
	 * Default constructor.
	 */
	public AbstractDroolsRuleRunner() {
	}
	
	/**
	 * Returns current container by session name.
	 *
	 * @param sessionName
	 * @return KieContainer
	 */
	protected abstract KieContainer getContainer(String sessionName);
	
	// @see org.kie.internal.utils.ServiceRegistryImpl
	// @see org.drools.compiler.kie.builder.impl.KieServicesImpl
	
	/**
	 * Run all matchable rules.
	 *
	 * @param name
	 * @param facts
	 */
	//public synchronized void runRules(String name , Object[] facts) {
	public void runRules(String name , Object[] facts) {
		//
		KieSession session = null;
		//
		try {
			/**
			 * Do create session.
			 */
			session = getContainer( name ).newKieSession( name );
			logger.info( "Started create session...{}" , session );
			
			/**
			 * Do insert fact objects.
			 */
			FactHandle[] factHandles = new FactHandle[ facts.length ];
			for ( int i = 0; i < facts.length; i++ ) {
				logger.trace( "Starting insert fact object...{}" , facts[i] );
				//
				factHandles[i] = session.insert( facts[i] );
			}
			/**
			 * Do execute all matchable rules.
			 */
			logger.info( "Starting fire all rules..." );
			session.fireAllRules();

			///**
			// * Delete fact handles.
			// */
			//for ( int i = 0; i < factHandles.length; i++ ) {
			//	logger.debug( "Starting delete fact handle...{}" , factHandles[i] );
			//	if ( factHandles[i] != null ) {
			//		session.delete( factHandles[i] );
			//	}
			//}
		}
		catch (Throwable t) {
			logger.error( "Current drools rules is error...\n{}" , ExceptionUtil.get( t ) );
		}
		finally {
			/**
			 * Do close session
			 */
			if ( session != null ) {
				logger.info( "Starting dispose session...{}" , session );
				session.dispose();
				session = null;
			}
		}
	}
	
	/**
	 * Returns the String representation.
	 *
	 * @return String
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append( "[" );
		builder.append( super.toString() );
		builder.append( "]" );
		//
		return builder.toString();
	}
}